package com.chen106106.sstest.common.session;

import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.filter.OncePerRequestFilter;

// Referenced classes of package yuanlai.commons.session:
//            HttpSessionRequestWrapper, HttpSessionResponseWrapper, HttpSessionManager

public class MemcachedSessionFilter extends OncePerRequestFilter
{

    public MemcachedSessionFilter()
    {
    }

    private String mixSessionId(String sessionIdInCookie, HttpServletRequest req)
    {
        if(StringUtils.isEmpty(sessionIdInCookie))
            return null;
        else
            return sessionIdInCookie;
    }

    protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain)
        throws ServletException, IOException
    {
        String sessionKey = sessionManager.getSessionKey();
        String cookiePath = sessionManager.getCookiePath();
        int sessionTimeout = sessionManager.getSessionTimeout();
        Cookie cookies[] = req.getCookies();
        String sessionIdInCookie = null;
        boolean sessionFromCookie = true;
        if(cookies != null && cookies.length > 0)
        {
            for(int i = 0; i < cookies.length; i++)
                if(cookies[i].getName().equals(sessionKey))
                    sessionIdInCookie = cookies[i].getValue();

        }
        if(sessionIdInCookie == null)
        {
            sessionIdInCookie = parseSessionIdFromUri(req);
            sessionFromCookie = false;
        }
        String sessionId = mixSessionId(sessionIdInCookie, req);
        HttpSession session = sessionManager.getSession(sessionId);
        if(session == null)
        {
            String newSessionId = RandomStringUtils.randomAlphanumeric(20);
            sessionId = mixSessionId(newSessionId, req);
            session = sessionManager.newSession(sessionId);
            Cookie sessionCookie = new Cookie(sessionKey, newSessionId);
            sessionCookie.setPath(cookiePath);
            res.addCookie(sessionCookie);
        }
        session.setMaxInactiveInterval(sessionTimeout * 60);
        req = new HttpSessionRequestWrapper(req, session);
        res = new HttpSessionResponseWrapper(res, session, sessionManager, sessionFromCookie);
        chain.doFilter(req, res);
        sessionManager.updateSession(session);
    }

    protected void initFilterBean()
        throws ServletException
    {
        WebApplicationContext spring = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
        sessionManager = (HttpSessionManager)spring.getBean("sessionManager");
        sessionSuffix = (new StringBuilder()).append(";").append(sessionManager.getSessionKey()).append("=").toString();
    }

    public void destroy()
    {
        sessionManager = null;
    }

    private String parseSessionIdFromUri(HttpServletRequest request)
    {
        String sessionId = null;
        String uri = request.getRequestURI();
        int p = uri.indexOf(sessionSuffix);
        if(p >= 0)
        {
            int suffixLength = sessionSuffix.length();
            int tail = uri.indexOf(';', p + suffixLength);
            if(tail > 0)
                sessionId = uri.substring(p + suffixLength, tail);
            else
                sessionId = uri.substring(p + suffixLength);
        }
        return sessionId;
    }

    private HttpSessionManager sessionManager;
    private String sessionSuffix;
}
